package com.jwater.core.metrics.system;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jwater.core.metrics.JvmMetric;
import com.jwater.core.utils.ProcessUtils;
import com.jwater.core.utils.SysType;

import jwater.org.apache.commons.io.IOUtils;
/**
 * @description:
 * @author: jnner
 * @createDate: 2021/2/5
 * @version: 1.0
 */
public class MemoryMetric {
	protected static Logger logger = LoggerFactory.getLogger(MemoryMetric.class);

	public static Map<String, Double> getHeapMemory() {
		return JvmMetric.getHeapMemory();
	}

	public static Map<String, Double> getNonHeapMemory() {
		return JvmMetric.getNonHeapMemory();
	}

	public static Map<String, Double> getSystemMemory() {
		String sysType = SysType.getSysType();
		if (SysType.WINDOWS.equals(sysType)) {
			return getSystemMemoryForWin();
		} else if (SysType.LINUX.equals(sysType)) {
			return getSystemMemoryForLinux();
		}
		return new HashMap<String, Double>();
	}

	private static Map<String, Double> getSystemMemoryForWin() {
		Map<String, Double> memory = new HashMap<String, Double>();
		try {
			Double free = 0d, total = 0d;
			String procCmd = System.getenv("windir") + "//system32//wbem//wmic.exe "
					+ "path win32_operatingsystem get freephysicalmemory,TotalVisibleMemorySize /value";
			List<String> result = ProcessUtils.cmd(null,procCmd);
			for (String msg : result) {
				msg = msg.trim();
				if (!msg.equals("")) {
					String[] items = msg.split("=");
					if ("FreePhysicalMemory".equals(items[0])) {
						free = Double.parseDouble(items[1]);
					} else if ("TotalVisibleMemorySize".equals(items[0])) {
						total = Double.parseDouble(items[1]);
					}
				}
			}
			memory.put("free", free / 1024);
			memory.put("total", total / 1024);
			memory.put("cached", 0d);
		} catch (Exception e) {
			logger.error(e.toString(), e);
		}
		return memory;
	}

	private static Map<String, Double> getSystemMemoryForLinux() {
		Map<String, Double> memory = new HashMap<String, Double>();
		try {
			double free = 0d, total = 0d, cached = 0d;
			FileInputStream fis = new FileInputStream("/proc/meminfo");
			List<String> lines = IOUtils.readLines(fis, "UTF-8");
			fis.close();
			for (String line : lines) {
				if (line.startsWith("MemTotal:")) {
					line = line.replace("MemTotal:", "").replace("kB", "").trim();
					total = Double.parseDouble(line);
				} else if (line.startsWith("MemFree:")) {
					line = line.replace("MemFree:", "").replace("kB", "").trim();
					free = Double.parseDouble(line);
				} else if (line.startsWith("Cached:")) {
					line = line.replace("Cached:", "").replace("kB", "").trim();
					cached = Double.parseDouble(line);
				}
			}
			memory.put("free", free / 1024);
			memory.put("total", total / 1024);
			memory.put("cached", cached / 1024);
		} catch (Exception e) {
			logger.error(e.toString(), e);
		}
		return memory;
	}
}
